package com.mes.spc.controller;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.lang.ArrayUtils;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;

import com.mes.entity.User;
import com.mes.spc.service.EmesqSpcCheckItemConfigService;
import com.mes.spc.service.EmesqSpcControlChartService;
import com.mes.spc.util.SpcCalUtil;
import com.yy.base.page.Message;
import com.yy.base.util.UserUtil;

@Controller
@RequestMapping("spc/controlchart")
public class EmesqSpcControlChartController {

	@Autowired
	private EmesqSpcCheckItemConfigService esccs;
	
	@Autowired
	private EmesqSpcControlChartService esControlChartService;
	
	@RequestMapping(value="getBaseInfo", method=RequestMethod.POST)
	@ResponseBody
	public Message getBaseInfo(HttpServletRequest request) {
		Message msg = new Message();
		String id = request.getParameter("configId");
		Map<String, Object> ckConfig = this.esccs.getSpcCkConfigById(id);
		msg.setData("ckConfig", ckConfig);
		return msg;
	}
	
	
	@RequestMapping(value="getSampleData", method=RequestMethod.POST)
	@ResponseBody
	public Message getSampleData(HttpServletRequest request) {
		Message msg = new Message();
		String configId = request.getParameter("configId");
		String scDate = request.getParameter("scDate");//抽检时间范围筛选
		String isSample = request.getParameter("isSample");//是否为样本筛选
		String remark1 = request.getParameter("remark1");
		String remark2 = request.getParameter("remark2");
		String remark3 = request.getParameter("remark3");
		String remark4 = request.getParameter("remark4");
		String remark5 = request.getParameter("remark5");
		Map<String,String> paramMap = new HashMap<String, String>();
		if(remark1!=null)paramMap.put("remark1", remark1);
		if(remark2!=null)paramMap.put("remark2", remark2);
		if(remark3!=null)paramMap.put("remark3", remark3);
		if(remark4!=null)paramMap.put("remark4", remark4);
		if(remark5!=null)paramMap.put("remark5", remark5);
		Map<String, Object> ckConfig = this.esccs.getSpcCkConfigById(configId);
		int maxNum = 2000;
		if("variables".equals(ckConfig.get("CHECKITEM_TYPE"))) {	//计量型
			Map<String,Object> checkMap = esControlChartService.checkDataNum(configId, isSample!=null&&isSample.equals("1")?true:false, scDate, paramMap);
			if(checkMap!=null&&checkMap.get("TOTAL")!=null&&Integer.parseInt(checkMap.get("TOTAL")+"")<maxNum){
				List<Map<String, Object>> data = this.esControlChartService.getSampleData(ckConfig, configId,isSample!=null&&isSample.equals("1")?true:false,scDate,paramMap);
				msg.setData("sampleData", data);
			}else{
				msg.setData("minDate", checkMap.get("MINDATE"));
				msg.setData("maxDate", checkMap.get("MAXDATE"));
				msg.setErrorMessage("分析数据量过大，已筛选近期数据展示!");
			}
		}
		if("counting".equals(ckConfig.get("CHECKITEM_TYPE"))) {	//计数型
			Map<String, Object> data = this.esControlChartService.getBadProductData(ckConfig, configId,isSample!=null&&isSample.equals("1")?true:false,scDate,paramMap);
			//获取样本数据的控制限上下值
	        String cxu = ckConfig.get("CONTROL_X_UPPER")==null?"":(ckConfig.get("CONTROL_X_UPPER")+"");
	        String cxl = ckConfig.get("CONTROL_X_LOWER")==null?"":(ckConfig.get("CONTROL_X_LOWER")+"");
	        String cx = ckConfig.get("CONTROL_X_VAL")==null?"":(ckConfig.get("CONTROL_X_VAL")+"");
	        //如果未查到相关设置的控制上限，则根据样本重新计算上下限
	        if(StringUtils.isEmpty(cxu)&&StringUtils.isEmpty(cxl)&&StringUtils.isEmpty(cx)){
	        	try {
	        		Map<String, Object> calData = esccs.calControl(configId,paramMap);
	        		cxu = (Double)calData.get("UCL")==0d?"":(calData.get("UCL")+"");
	        		cxl = (Double)calData.get("LCL")==0d?"":(calData.get("LCL")+"");
	        		cx = (Double)calData.get("CL")==0d?"":(calData.get("CL")+"");
				} catch (Exception e) {
					
				}
	        }
	        if(StringUtils.isNotEmpty(cxu)&&StringUtils.isNotEmpty(cxl)&&StringUtils.isNotEmpty(cx)){
		        data.put("cl", SpcCalUtil.ZeroFormat(Double.parseDouble(cx), 4));
		        data.put("ucl", SpcCalUtil.ZeroFormat(Double.parseDouble(cxu), 4));
		        data.put("lcl", SpcCalUtil.ZeroFormat(Double.parseDouble(cxl), 4));
	        }
			msg.setData(data);
			if(data.size()>maxNum){
				msg.setErrorMessage("分析数据量过大!");
			}
		}
		return msg;
	}
	
	@RequestMapping(value="getConfig", method=RequestMethod.POST)
	@ResponseBody
	public Message getConfig(HttpServletRequest request) {
		Message msg = new Message();
		String configId = request.getParameter("configId");
		Map<String,Object> configObject = esccs.getConfig(configId);
		msg.setData("config",configObject);
		return msg;
	}
	
	@RequestMapping(value="setConfig", method=RequestMethod.POST)
	@ResponseBody
	public Message setConfig(HttpServletRequest request) {
		Message msg = new Message();
		String configId = request.getParameter("configId");
		String uslStr = request.getParameter("usl");
		String lslStr = request.getParameter("lsl");
		String targetStr = request.getParameter("target");
		if(!(SpcCalUtil.isDouble(uslStr)&&SpcCalUtil.isDouble(lslStr)&&SpcCalUtil.isDouble(targetStr))){
			msg.setErrorMessage("修改失败！");
			return msg;
		}
		double usl = Double.parseDouble(uslStr);
		double lsl = Double.parseDouble(lslStr);
		double target = Double.parseDouble(targetStr);
		if(esccs.setConfig(configId, usl, lsl, target)){
			msg.setOkMessage("修改成功！");
		}
		return msg;
	}
	
	@RequestMapping(value="savCalControl", method=RequestMethod.POST)
	@ResponseBody
	public Message setControl(HttpServletRequest request) {
		Message msg = new Message();
		String configId = request.getParameter("configId");
		String uslStr = request.getParameter("ucl");
		String lslStr = request.getParameter("lcl");
		String targetStr = request.getParameter("target");
		if(!(SpcCalUtil.isDouble(uslStr)&&SpcCalUtil.isDouble(lslStr)&&SpcCalUtil.isDouble(targetStr))){
			msg.setErrorMessage("修改失败！");
			return msg;
		}
		double usl = Double.parseDouble(uslStr);
		double lsl = Double.parseDouble(lslStr);
		double target = Double.parseDouble(targetStr);
		if(esccs.setControl(configId, usl, lsl, target)){
			msg.setOkMessage("修改成功！");
		}
		return msg;
	}
	
	/**
	 * 新增数据
	 * @param request
	 * @param configId
	 * @param checkDate
	 * @param checkCount
	 * @param sampleDataStr
	 * @param badTypeCodeStr
	 * @param checkItemType
	 * @param graphType
	 * @param isSample
	 * @return
	 */
	@RequestMapping(value="addData", method=RequestMethod.POST)
	@ResponseBody
	public Message addData(HttpServletRequest request,String configId,String checkDate,String checkCount,String sampleDataStr,
			String badTypeCodeStr,String checkItemType,String graphType,String isSample,String curEditCalcId) {
		Message msg = new Message();
		User user = (User)request.getSession().getAttribute(UserUtil.USERSESSION);
		String orgId = (String)request.getSession().getAttribute("orgId");
		try {
			if(StringUtils.isEmpty(curEditCalcId)){
				esControlChartService.addData(configId, checkDate,checkCount, sampleDataStr, badTypeCodeStr, checkItemType,graphType,isSample,user,orgId);
			}else{
				esControlChartService.editData(configId,curEditCalcId, checkDate,checkCount, sampleDataStr, badTypeCodeStr, checkItemType,graphType,isSample,user,orgId);
			}
			msg.setOkMessage("操作成功！");
		} catch (Exception e) {
			msg.setErrorMessage("操作失败！"+e.getMessage());
			e.printStackTrace();
		}
		return msg;
	}
	
	@RequestMapping(value="delCalData", method=RequestMethod.POST)
	@ResponseBody
	public Message delCalData(HttpServletRequest request,String configId,String calcId) {
		Message msg = new Message();
		User user = (User)request.getSession().getAttribute(UserUtil.USERSESSION);
		String orgId = (String)request.getSession().getAttribute("orgId");
		try {
			if(StringUtils.isNotEmpty(calcId)){
				esControlChartService.delCalData(configId,calcId,user,orgId);
			}else{
				msg.setOkMessage("操作失败！");
			}
			msg.setOkMessage("操作成功！");
		} catch (Exception e) {
			msg.setOkMessage("操作失败！");
			e.printStackTrace();
		}
		return msg;
	}
	
	//执行判异规则进行状态更新
	@RequestMapping(value="executeCheckRule", method=RequestMethod.POST)
	@ResponseBody
	public Message executeCheckRule(HttpServletRequest request) {
		Message msg = new Message();
		String configId = request.getParameter("configId");
		String scDate = request.getParameter("scDate");
		String isSample = request.getParameter("isSample");
		String remark1 = request.getParameter("remark1");
		String remark2 = request.getParameter("remark2");
		String remark3 = request.getParameter("remark3");
		String remark4 = request.getParameter("remark4");
		String remark5 = request.getParameter("remark5");
		Map<String,String> paramMap = new HashMap<String, String>();
		if(remark1!=null)paramMap.put("remark1", remark1);
		if(remark2!=null)paramMap.put("remark2", remark2);
		if(remark3!=null)paramMap.put("remark3", remark3);
		if(remark4!=null)paramMap.put("remark4", remark4);
		if(remark5!=null)paramMap.put("remark5", remark5);
		boolean isSampleFlag = true;
		if(isSample!=null&&isSample.equals("1")){
			isSampleFlag = true;
	    }else{
	    	isSampleFlag = false;
	    }
		User user = (User)request.getSession().getAttribute(UserUtil.USERSESSION);
		String orgId = (String)request.getSession().getAttribute("orgId");
		
		if(StringUtils.isEmpty(configId)){
			msg.setErrorMessage("缺少必要字段！");
			return msg;
		}
		double UCL = 0d;//控制上限
        double LCL = 0d;//控制下限
        double CL = 0d;//控制中线 所有样本均值
        
        Map<String, Object> ckConfig = this.esccs.getSpcCkConfigById(configId);
        //查询当前控制上下限是否已经设置
        String cxu = ckConfig.get("CONTROL_X_UPPER")==null?"":(ckConfig.get("CONTROL_X_UPPER")+"");
        String cxl = ckConfig.get("CONTROL_X_LOWER")==null?"":(ckConfig.get("CONTROL_X_LOWER")+"");
        String cx = ckConfig.get("CONTROL_X_VAL")==null?"":(ckConfig.get("CONTROL_X_VAL")+"");
        
        //图标类型
        String graphType = ckConfig.get("GRAPH_TYPE")+"";
        if(graphType.equals("P")||graphType.equals("U")||
        		graphType.equals("C")||graphType.equals("nP")){//计数型
        	Map<String, Object> ts = esControlChartService.getBadProductData(ckConfig, configId,isSampleFlag,scDate,paramMap);
        	CL = (Double)ts.get("cl");
        	UCL = (Double)ts.get("rucl");
        	LCL = (Double)ts.get("rlcl");
        	if(CL==0d&&UCL==0d&&LCL==0d){
        		msg.setErrorMessage("未查到样本数据，无法计算！");
                return msg;
        	}
        	List<Double> badCountList = null;
        	List<String> calcIdList = (List<String>)ts.get("calcIdList");
        	if("P".equals(graphType) || "U".equals(graphType)) {//比较比率
        		badCountList = (List<Double>)ts.get("badRateList");
    		}else{//比较数量
    			badCountList = (List<Double>)ts.get("badCountList");
    		}
        	try {
        		if(StringUtils.isNotEmpty(cxu)&&StringUtils.isNotEmpty(cxl)&&StringUtils.isNotEmpty(cx)){
        			CL = Double.parseDouble(cx);
        			UCL = Double.parseDouble(cxu);
        			LCL = Double.parseDouble(cxl);
        		}
				esccs.executeCountCheckRule(configId,calcIdList, badCountList, UCL, LCL, CL, user, orgId);
				msg.setOkMessage("执行成功！");
			} catch (Exception e) {
				msg.setErrorMessage(e.getMessage());
				e.printStackTrace();
			}
        }else{//计量型
        	Map<String, Object> arrayDataMap = esControlChartService.getSampleArrayData(ckConfig,configId,isSampleFlag,scDate,paramMap);
            if(checkData(arrayDataMap)){
            	msg.setErrorMessage("未查到样本数据！");
                return msg;
            }
            double[] avgArray = ArrayUtils.toPrimitive((Double[])arrayDataMap.get("avgArray"));//样本均值
            double[] avgRArray = ArrayUtils.toPrimitive((Double[])arrayDataMap.get("avgRArray"));//极差平均值
            double[] stdevArray = ArrayUtils.toPrimitive((Double[])arrayDataMap.get("avgStdevArray"));//标准差均值
            String[] calcIdArray = (String[])arrayDataMap.get("calcIdArray");//样本ID的集合;
            double[] arrData = ArrayUtils.toPrimitive((Double[])arrayDataMap.get("arrData"));//所有样本
            int sampleSize = Integer.parseInt(ckConfig.get("SAMPLE_VOLUME")+"");//样本容量
            double LSL = Double.parseDouble(ckConfig.get("SPECIFICA_LOWER")==null?SpcCalUtil.ErrNum +"":(ckConfig.get("SPECIFICA_LOWER")+""));
            double USL =  Double.parseDouble(ckConfig.get("SPECIFICA_UPPER")==null?SpcCalUtil.ErrNum +"":(ckConfig.get("SPECIFICA_UPPER")+""));
            
            double CL_R = SpcCalUtil.avage(avgRArray);//极差平均值
            //根据图形计算控制线上下值
            if(ckConfig.get("GRAPH_TYPE").equals("IMR")){
            	double sumJc = 0d;//移动极差的和
                for(int i = 1;i<avgArray.length;i++){
                    sumJc+=Math.max(avgArray[i],avgArray[i-1])-Math.min(avgArray[i],avgArray[i-1]);
                }
                int w = 2;//移动极差的长度。默认值为 2。
                double avgSumJc = sumJc/((avgArray.length-w+1)*1d);//移动极差平均值
                double stdev = avgSumJc/SpcCalUtil.D2ConstantNum[w-2];

                CL = SpcCalUtil.avage(avgArray);//样板平均值
                //计算均值
                UCL = CL+stdev*3;
                LCL = CL-stdev*3;
            }else{
    	        CL = SpcCalUtil.avage(avgArray);//样板平均值
    	        //计算均值
    	        UCL = SpcCalUtil.ZeroFormat(CL+SpcCalUtil.A2ConstantNum[sampleSize-2]*CL_R,3);
    	        LCL = SpcCalUtil.ZeroFormat(CL-SpcCalUtil.A2ConstantNum[sampleSize-2]*CL_R,3);
            }
            try {
            	if(StringUtils.isNotEmpty(cxu)&&StringUtils.isNotEmpty(cxl)&&StringUtils.isNotEmpty(cx)){
        			CL = Double.parseDouble(cx);
        			UCL = Double.parseDouble(cxu);
        			LCL = Double.parseDouble(cxl);
        		}
    			esccs.executeCheckRule(configId, calcIdArray, avgArray, USL, LSL, UCL, LCL, CL,user,orgId);
    			msg.setOkMessage("执行成功！");
    		} catch (Exception e) {
    			msg.setErrorMessage(e.getMessage());
    			e.printStackTrace();
    		}
        }
        
		return msg;
	}
	
	/**
	 * 导出Excel
	 * @param request
	 * @param response
	 * @return
	 */
	@RequestMapping(value="doExportExcel", method=RequestMethod.GET)
	@ResponseBody
	public void doExportExcel(HttpServletRequest request,HttpServletResponse response) {
		String configId = request.getParameter("configId");
		String scDate = request.getParameter("scDate");
		String isSample = request.getParameter("isSample");
		String remark1 = request.getParameter("remark1");
		String remark2 = request.getParameter("remark2");
		String remark3 = request.getParameter("remark3");
		String remark4 = request.getParameter("remark4");
		String remark5 = request.getParameter("remark5");
		Map<String,String> paramMap = new HashMap<String, String>();
		if(remark1!=null)paramMap.put("remark1", remark1);
		if(remark2!=null)paramMap.put("remark2", remark2);
		if(remark3!=null)paramMap.put("remark3", remark3);
		if(remark4!=null)paramMap.put("remark4", remark4);
		if(remark5!=null)paramMap.put("remark5", remark5);
		boolean isSampleFlag = true;
		if(isSample!=null&&isSample.equals("1")){
			isSampleFlag = true;
	    }else{
	    	isSampleFlag = false;
	    }
		
		esControlChartService.doExportExcel(configId,isSampleFlag,scDate,paramMap,response);
	}
	
	private boolean checkData(Map<String, Object> arrayDataMap){
        return arrayDataMap==null||Integer.parseInt(arrayDataMap.get("dataSize")+"")==0;
    }
}
